package com.ouc.dao.impl;

import com.ouc.common.utils.TextUtils;
import com.ouc.dao.NavigationDao;
import com.ouc.domain.*;
import org.springframework.stereotype.Repository;

import javax.swing.event.ListDataEvent;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

@Repository
public class NavigationDaoImpl implements NavigationDao {

  private void creatFile(String s, String filePath) {
    try {
      TextUtils.txtWrite(s, filePath);
    } catch (Exception e) {
      return;
    }
  }

  private String runExe(String cmdStr) {
    try {
      Process process = Runtime.getRuntime().exec(cmdStr);
      BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
      String line = null;
      StringBuilder build = new StringBuilder();
      while ((line = br.readLine()) != null) {
        // 将读取的每一行命令输出追加到字符串构建器中
        build.append(line);
      }
      System.out.println("build = " + build);
      return build.toString();
    } catch (Exception e) {
      return e.toString();
    }
  }

  @Override
  public int creatPre(PreFile preFile) {
    StringBuilder sb = new StringBuilder();
    sb.append(preFile.getJobName()).append("\r\n")
        .append(preFile.getJobTime()).append("\r\n")
        .append(preFile.getMinLat()).append(" ").append(preFile.getMaxLat()).append(" ").append(preFile.getMinLon()).append(" ").append(preFile.getMaxLon()).append("\r\n")
        .append(preFile.getNx()).append(" ").append(preFile.getNy()).append("\r\n")
        .append(preFile.getBtyFileName()).append("\r\n")
        .append(preFile.getWindFileName()).append("\r\n")
        .append(preFile.getCurFileName()).append("\r\n")
        .append(preFile.getWaveFileName()).append("\r\n");
    creatFile(sb.toString(), preFile.getPreFilePath());
    return 0;
  }

  @Override
  public String runPre(String preDir) {
    String cmdStr = "cmd /c cd /d " + preDir + " && preprocess.exe";
    return runExe(cmdStr);
  }

  public PreFile getEnv(String fileDir, String jobName) {
    PreFile preFile = new PreFile();
    preFile.setPreFilePath(fileDir);
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(fileDir + File.separator + jobName + ".env"))));
      preFile.setJobName(br.readLine());
      preFile.setJobTime(br.readLine());
      String[] split = br.readLine().split(" ");
      if (split.length >= 4) {
        preFile.setMinLat(Float.parseFloat(split[0]));
        preFile.setMaxLat(Float.parseFloat(split[1]));
        preFile.setMinLon(Float.parseFloat(split[2]));
        preFile.setMaxLon(Float.parseFloat(split[3]));
      }
      split = br.readLine().split(" ");
      if (split.length >= 2) {
        preFile.setNx(Integer.parseInt(split[0]));
        preFile.setNy(Integer.parseInt(split[1]));
      }
      return preFile;
    } catch (Exception e) {
      return null;
    }
  }

  public List<Float[][]> getOneFile(String filePath, Integer nx, Integer ny, Integer variableNum) {
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      br.readLine();
      br.readLine();
      br.readLine();
      br.readLine();
      List<Float[][]> resultList = new ArrayList<>();
      for (int t = 0; t < variableNum; t++) {
        Float[][] result = new Float[ny][nx];
        for (int i = 0; i < ny; i++) {
          String[] split = br.readLine().split(" ");
          for (int j = 0; j < nx; j++) {
            result[i][j] = Float.parseFloat(split[j]);
          }
        }
        resultList.add(result);
      }
      return resultList;
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  public PreFile getPreResult(PreFile preFile) {
    String fileDir = preFile.getPreFilePath();
    PreFile preResult = getEnv(fileDir, preFile.getJobName());
    String filePath = fileDir + File.separator + preFile.getJobName();
    preResult.setBtyFile(getOneFile(filePath + ".bty", preResult.getNx(), preResult.getNy(), 1));
    preResult.setCuFile(getOneFile(filePath + ".cu", preResult.getNx(), preResult.getNy(), 2));
    preResult.setWiFile(getOneFile(filePath + ".wi", preResult.getNx(), preResult.getNy(), 2));
    preResult.setWaFile(getOneFile(filePath + ".wa", preResult.getNx(), preResult.getNy(), 3));
    return preResult;
  }

  @Override
  public PreFile getPreWaFile(PreFile preFile) {
    String fileDir = preFile.getPreFilePath();
    PreFile preResult = getEnv(fileDir, preFile.getJobName());
    String filePath = fileDir + File.separator + preFile.getJobName();
    preResult.setWaFile(getOneFile(filePath + ".wa", preResult.getNx(), preResult.getNy(), 3));
    return preResult;
  }

  @Override
  public int creatMain(MainFile mainFile) {
    StringBuilder sb = new StringBuilder();
    sb.append(mainFile.getJobName()).append("\r\n")
        .append(mainFile.getJobTime()).append("\r\n")
        .append(mainFile.getMinLat()).append(" ").append(mainFile.getMaxLat()).append(" ")
        .append(mainFile.getMinLon()).append(" ").append(mainFile.getMaxLon()).append("\r\n")
        .append(mainFile.getNx()).append(" ").append(mainFile.getNy()).append(" ").append(mainFile.getStartY()).append(" ").append(mainFile.getStartX()).append(" ")
        .append(mainFile.getEndY()).append(" ").append(mainFile.getEndX()).append("\r\n");
    if (mainFile.getPointNum() == 0) {
      sb.append("0\r\n");
    } else {
      sb.append(mainFile.getPointNum());
      for (Integer point : mainFile.getPointList()) {
        sb.append(" ").append(point);
      }
      sb.append("\r\n");
    }
    sb.append(mainFile.getMaxWind()).append(" ").append(mainFile.getMaxCur()).append(" ")
        .append(mainFile.getMaxWave()).append(" ").append(mainFile.getMaxBty()).append("\r\n");
    for (Float f : mainFile.getShipVariable()) {
      sb.append(f).append(" ");
    }
    sb.append("\r\n");
    for (Integer i : mainFile.getFileVariable()) {
      sb.append(i).append(" ");
    }
    sb.append("\r\n");
    sb.append(mainFile.getModuleType()).append("\r\n");
    creatFile(sb.toString(), mainFile.getMainFilePath());
    return 0;
  }

  @Override
  public String runMain(String mainDir) {
    String cmdStr = "cmd /c cd /d " + mainDir + " && main.exe";
    return runExe(cmdStr);
  }

  private MainOutFile getOutFile(String filePath) {
    try {
      MainOutFile result = new MainOutFile();
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      result.setJobName(br.readLine());
      result.setJobTime(br.readLine());
      String[] split = br.readLine().split(" ");
      result.setMinLat(Double.parseDouble(split[0]));
      result.setMaxLat(Double.parseDouble(split[1]));
      result.setMinLon(Double.parseDouble(split[2]));
      result.setMaxLon(Double.parseDouble(split[3]));
      split = br.readLine().split(" ");
      Integer nx = Integer.parseInt(split[0]), ny = Integer.parseInt(split[1]);
      result.setNx(nx);
      result.setNy(ny);
      result.setStartY(Integer.parseInt(split[2]));
      result.setStartX(Integer.parseInt(split[3]));
      result.setEndY(Integer.parseInt(split[4]));
      result.setEndX(Integer.parseInt(split[5]));
      String s1 = br.readLine();
      if (s1.contains(" ")) {
        split = s1.split(" ");
        result.setPointNum(Integer.parseInt(split[0]));
        List<Integer> pointList = new ArrayList<>();
        for (int i = 1; i < split.length; i++) {
          pointList.add(Integer.parseInt(split[i]));
        }
        result.setPointList(pointList);
      } else {
        result.setPointNum(0);
      }
      split = br.readLine().split(" ");
      List<Float> shipVariableList = new ArrayList<>();
      for (String s : split) {
        shipVariableList.add(Float.parseFloat(s));
      }
      result.setShipVariable(shipVariableList);
      result.setModuleType(Integer.parseInt(br.readLine()));

      List<ShipPathAll> shipPathAllList = new ArrayList<>();
      String read = br.readLine();
      while (read != null) {
        String[] splitRead = read.split(" ");
        ShipPathAll shipPathAll = new ShipPathAll();
        shipPathAll.setModuleType(Integer.parseInt(splitRead[0]));
        shipPathAll.setSumDistance(Double.parseDouble(splitRead[1]));
        shipPathAll.setSumTime(Double.parseDouble(splitRead[2]));
        shipPathAll.setSumNumber(Integer.parseInt(splitRead[3]));

        List<ShipPathList> shipPathLists = new ArrayList<>();
        for (int i = 0; i < shipPathAll.getSumNumber(); i++) {
          ShipPathList shipPathList = new ShipPathList();
          splitRead = br.readLine().split(" ");
          shipPathList.setModelType(Integer.parseInt(splitRead[0]));
          shipPathList.setShipPathNumber(Integer.parseInt(splitRead[1]));
          shipPathList.setStartY(Integer.parseInt(splitRead[2]));
          shipPathList.setStartX(Integer.parseInt(splitRead[3]));
          shipPathList.setPointY(Integer.parseInt(splitRead[4]));
          shipPathList.setPointX(Integer.parseInt(splitRead[5]));
          shipPathList.setShipPathDistance(Double.parseDouble(splitRead[6]));
          shipPathList.setShipPathTime(Double.parseDouble(splitRead[7]));
          shipPathList.setShipPathSumNumber(Integer.parseInt(splitRead[8]));
          List<ShipPath> shipPaths = new ArrayList<>();
          for (int j = 0; j < shipPathList.getShipPathSumNumber(); j++) {
            ShipPath shipPath = new ShipPath();
            splitRead = br.readLine().split(" ");
            shipPath.setNum(Integer.parseInt(splitRead[0]));
            shipPath.setStartY(Integer.parseInt(splitRead[1]));
            shipPath.setStartX(Integer.parseInt(splitRead[2]));
            shipPath.setEndY(Integer.parseInt(splitRead[3]));
            shipPath.setEndX(Integer.parseInt(splitRead[4]));
            shipPath.setDistance(Double.parseDouble(splitRead[5]));
            shipPath.setTime(Double.parseDouble(splitRead[6]));
            shipPath.setVelocity(Double.parseDouble(splitRead[7]));
            shipPath.setWindVelocity(Double.parseDouble(splitRead[8]));
            shipPath.setWindDirection(Double.parseDouble(splitRead[9]));
            shipPath.setCurVelocity(Double.parseDouble(splitRead[10]));
            shipPath.setCurDirection(Double.parseDouble(splitRead[11]));
            shipPath.setWaveDirection(Double.parseDouble(splitRead[12]));
            shipPath.setWavePeriod(Double.parseDouble(splitRead[13]));
            shipPath.setWaveHeight(Double.parseDouble(splitRead[14]));
            shipPath.setShipDirection(Double.parseDouble(splitRead[15]));
            shipPaths.add(shipPath);
          }
          shipPathList.setShipPathList(shipPaths);
          shipPathLists.add(shipPathList);
        }
        shipPathAll.setShipPathLists(shipPathLists);
        shipPathAllList.add(shipPathAll);
        read = br.readLine();
      }
      result.setShipPathAllList(shipPathAllList);

      /*
      List<ShipPathList> shipPathLists = new ArrayList<>();
      ShipPathList shipPathList = new ShipPathList();
      split = br.readLine().split(" ");
      shipPathList.setModuleType(Integer.parseInt(split[0]));
      shipPathList.setSumDistance(Double.parseDouble(split[1]));
      shipPathList.setSumTime(Double.parseDouble(split[2]));

      List<ShipPath> shipPaths = new ArrayList<>();
      String brRead = br.readLine();
      while (brRead != null) {
        String[] split1 = brRead.split(" ");
        if (split1.length == 16) {
          ShipPath shipPath = new ShipPath();
          shipPath.setNum(Integer.parseInt(split1[0]));
          shipPath.setStartY(Integer.parseInt(split1[1]));
          shipPath.setStartX(Integer.parseInt(split1[2]));
          shipPath.setEndY(Integer.parseInt(split1[3]));
          shipPath.setEndX(Integer.parseInt(split1[4]));
          shipPath.setDistance(Double.parseDouble(split1[5]));
          shipPath.setTime(Double.parseDouble(split1[6]));
          shipPath.setVelocity(Double.parseDouble(split1[7]));
          shipPath.setWindVelocity(Double.parseDouble(split1[8]));
          shipPath.setWindDirection(Double.parseDouble(split1[9]));
          shipPath.setCurVelocity(Double.parseDouble(split1[10]));
          shipPath.setCurDirection(Double.parseDouble(split1[11]));
          shipPath.setWaveDirection(Double.parseDouble(split1[12]));
          shipPath.setWavePeriod(Double.parseDouble(split1[13]));
          shipPath.setWaveHeight(Double.parseDouble(split1[14]));
          shipPath.setShipDirection(Double.parseDouble(split1[15]));
          shipPaths.add(shipPath);
        } else if (split1.length == 3) {
          shipPathList.setShipPathList(shipPaths);
          shipPaths = new ArrayList<>();
          shipPathLists.add(shipPathList);
          shipPathList = new ShipPathList();
          shipPathList.setModuleType(Integer.parseInt(split1[0]));
          shipPathList.setSumDistance(Double.parseDouble(split1[1]));
          shipPathList.setSumTime(Double.parseDouble(split1[2]));
        }
        brRead = br.readLine();
      }
      shipPathList.setShipPathList(shipPaths);
      shipPathLists.add(shipPathList);
      result.setShipPathLists(shipPathLists);*/
      return result;
    } catch (Exception e) {
      return null;
    }
  }

  private String[][] getMapOutFile(String filePath, Integer nx, Integer ny) {
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      br.readLine();
      br.readLine();
      br.readLine();
      br.readLine();
      br.readLine();
      String[][] result = new String[ny][nx];
      for (int i = 0; i < ny; i++) {
        String[] split = br.readLine().split(" ");
        for (int j = 0; j < nx; j++) {
          result[i][j] = split[j];
        }
      }
      return result;
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  public MainOutFile getMainOutFile(String fileDir, String jobName) {
    MainOutFile mainOutFile = getOutFile(fileDir + File.separator + jobName + ".out");
    mainOutFile.setOutMap(getMapOutFile(fileDir + File.separator + jobName + "_map.out", mainOutFile.getNx(), mainOutFile.getNy()));
    return mainOutFile;
  }

  @Override
  public String creatMapInFile(MainOutFile mainOutFile) {
    String filePath = mainOutFile.getOutFileDir() + File.separator + mainOutFile.getJobName() + "_map.in";
    StringBuilder sb = new StringBuilder();
    sb.append(mainOutFile.getJobName()).append("\r\n")
        .append(mainOutFile.getJobTime()).append("\r\n")
        .append(mainOutFile.getMinLat()).append(" ").append(mainOutFile.getMaxLat()).append("")
        .append(mainOutFile.getMinLon()).append(" ").append(mainOutFile.getMaxLon()).append("\r\n")
        .append(mainOutFile.getNx()).append(" ").append(mainOutFile.getNy()).append("\r\n");
    for (Float f : mainOutFile.getShipVariable()) {
      sb.append(f).append(" ");
    }
    sb.append("\r\n");
    for (int i = 0; i < mainOutFile.getNy(); i++) {
      for (int j = 0; j < mainOutFile.getNx(); j++) {
        sb.append(mainOutFile.getOutMap()[i][j]).append(" ");
      }
      sb.append("\r\n");
    }
    creatFile(sb.toString(), filePath);
    return filePath;
  }

  @Override
  public int creatSpectrumSetting(SpectrumSetting spectrumSetting) {
    StringBuilder sb = new StringBuilder();
    sb.append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("//                               Input file                                     //").append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("                    RAO file: ").append(spectrumSetting.getRaoFileName()).append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("\r\n")
        .append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("//                                 Information                                  //").append("\r\n")
        .append("//                                                                              //").append("\r\n")
        .append("//                        work condition number : ").append(spectrumSetting.getWorkConditionNumber()).append("                    //").append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("       Signification wave height (m) :").append(spectrumSetting.doubleListToString(spectrumSetting.getWaveHeight())).append("\r\n")
        .append("       Average wave Period (s) :").append(spectrumSetting.doubleListToString(spectrumSetting.getWavePeriod())).append("\r\n")
        .append("       Target ship speed (m/s) :").append(spectrumSetting.doubleListToString(spectrumSetting.getShipSpeed())).append("\r\n")
        .append("       Target wave direction (deg) :").append(spectrumSetting.doubleListToString(spectrumSetting.getWaveDirection())).append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("\r\n")
        .append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("//                            Indicator parameters                              //").append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n")
        .append("            DF:").append(spectrumSetting.getDf()).append("\r\n")
        .append("            Lpp:").append(spectrumSetting.getLpp()).append("\r\n")
        .append("            TSL:").append(spectrumSetting.getTsl()).append("\r\n")
        .append("            ZPROP:").append(spectrumSetting.getZprop()).append("\r\n")
        .append("            DPROP:").append(spectrumSetting.getDprop()).append("\r\n")
        .append("//------------------------------------------------------------------------------//").append("\r\n");
    creatFile(sb.toString(), spectrumSetting.getFileDir());
    return 0;
  }

  @Override
  public String runSpectrum(String spectrumDir) {
    String cmdStr = "cmd /c cd /d " + spectrumDir + " && Project1.exe";
    return runExe(cmdStr);
  }

  private List<Double> stringToList(String s) {
    List<Double> result = new ArrayList<>();
    String[] split = s.split("：")[1].split(" ");
    for (String s1 : split) {
      result.add(stringToDouble(s1));
    }
    return result;
  }

  private Double stringToDouble(String s) {
    if (s.contains("nan")) {
      return Double.NaN;
    } else {
      return Double.parseDouble(s);
    }
  }

  @Override
  public List<SpectrumResult> getSpectrumResult(String spectrumDir) {
    try {
      List<SpectrumResult> spectrumResultList = new ArrayList<>();
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(spectrumDir + File.separator + "results.txt")), Charset.forName("GBK")));
      String s = br.readLine();
      while (s != null && s.contains("工况")) {
        SpectrumResult spectrumResult = new SpectrumResult();
        spectrumResult.setDisplacement(stringToList(br.readLine()));
        spectrumResult.setSpeed(stringToList(br.readLine()));
        spectrumResult.setAcceleration(stringToList(br.readLine()));
        spectrumResult.setWi(stringToDouble(br.readLine().split("=")[1]));
        spectrumResult.setSi(stringToDouble(br.readLine().split("=")[1]));
        spectrumResult.setPe(stringToDouble(br.readLine().split("=")[1]));
        spectrumResultList.add(spectrumResult);
        s = br.readLine();
        s = br.readLine();
      }
      return spectrumResultList;
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  public List<SpectrumResult> getSpectrumResultDemo(String spectrumDir, String resultFileName) {
    try {
      List<SpectrumResult> spectrumResultList = new ArrayList<>();
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(spectrumDir + File.separator + resultFileName + ".txt")), Charset.forName("GBK")));
      String s = br.readLine();
      while (s != null && s.contains("工况")) {
        SpectrumResult spectrumResult = new SpectrumResult();
        spectrumResult.setDisplacement(stringToList(br.readLine()));
        spectrumResult.setSpeed(stringToList(br.readLine()));
        spectrumResult.setAcceleration(stringToList(br.readLine()));
        spectrumResult.setWi(stringToDouble(br.readLine().split("=")[1]));
        spectrumResult.setSi(stringToDouble(br.readLine().split("=")[1]));
        spectrumResult.setPe(stringToDouble(br.readLine().split("=")[1]));
        spectrumResultList.add(spectrumResult);
        s = br.readLine();
        s = br.readLine();
      }
      return spectrumResultList;
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  public int creatPointSafety(PointSafety pointSafety) {
    StringBuilder sb = new StringBuilder();
    sb
        .append("//                               ProjectName Time                                //").append("\r\n")
        .append(pointSafety.getProjectName()).append(" ").append(pointSafety.getProjectTime()).append("\r\n")
        .append("//                               model selection                                    //").append("\r\n")
        .append(pointSafety.getModelSelection()).append("\r\n")
        .append("//                               wind parameters : wind speed(m/s) wind direction(deg)                                          //").append("\r\n")
        .append(pointSafety.getWindSpeed()).append(" ").append(pointSafety.getWindDirection()).append("\r\n")
        .append("//                               wave parameters : wave height(m) wave direction(deg) wave period(s)                 //").append("\r\n")
        .append(pointSafety.getWaveHeight() + " " + pointSafety.getWaveDirection() + " " + pointSafety.getWavePeriod()).append("\r\n")
        .append("//                               current parameters : current speed(m/s) current direction(deg)                             //").append("\r\n")
        .append(pointSafety.getCurrentSpeed() + " " + pointSafety.getCurrentDirection()).append("\r\n")
        .append("//                               ship parameters : draft(m) length(m) width(m) displacement(ton) speed(knot/h) direction(deg)  //").append("\r\n")
        .append(pointSafety.getShipDraft() + " " + pointSafety.getShipLength() + " " + pointSafety.getShipWidth() + " " + pointSafety.getShipDisplacement()
            + " " + pointSafety.getShipSpeed() + " " + pointSafety.getShipDirection()).append("\r\n");
    creatFile(sb.toString(), pointSafety.getFileDir());
    return 0;
  }

  @Override
  public String runPointSafety(String pointSafetyDir) {
    String cmdStr = "cmd /c cd /d " + pointSafetyDir + " && rote_safety_analysis_testmode.exe";
    return runExe(cmdStr);
  }

  private PointSafety getPointSafetyOutFile(String filePath) {
    try {
      PointSafety result = new PointSafety();
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      String read = br.readLine();
      String[] split = br.readLine().split(" ");
      result.setProjectName(split[0]);
      result.setProjectTime(split[1]);
      br.readLine();
      read = br.readLine();
      result.setModelSelection(Integer.parseInt(read));
      br.readLine();
      split = br.readLine().split(" ");
      result.setWindSpeed(Double.parseDouble(split[0]));
      result.setWindDirection(Double.parseDouble(split[1]));
      br.readLine();
      split = br.readLine().split(" ");
      result.setWaveHeight(Double.parseDouble(split[0]));
      result.setWaveDirection(Double.parseDouble(split[1]));
      result.setWavePeriod(Double.parseDouble(split[2]));
      br.readLine();
      split = br.readLine().split(" ");
      result.setCurrentSpeed(Double.parseDouble(split[0]));
      result.setCurrentDirection(Double.parseDouble(split[1]));
      br.readLine();
      split = br.readLine().split(" ");
      result.setShipDraft(Double.parseDouble(split[0]));
      result.setShipLength(Double.parseDouble(split[1]));
      result.setShipWidth(Double.parseDouble(split[2]));
      result.setShipDisplacement(Double.parseDouble(split[3]));
      result.setShipSpeed(Double.parseDouble(split[4]));
      result.setShipDirection(Double.parseDouble(split[5]));
      br.readLine();
      split = br.readLine().split(" ");
      result.setSurge(Double.parseDouble(split[0]));
      result.setSway(Double.parseDouble(split[1]));
      result.setYaw(Double.parseDouble(split[2]));
      result.setRoll(Double.parseDouble(split[3]));
      return result;
    } catch (Exception e) {
      return null;
    }
  }

  private List<List<Double>> getPointSafetyValue(String filePath) {
    try {
      List<List<Double>> result = new ArrayList<>();
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      String s = br.readLine();
      while (s != null) {
        String[] split = s.split(",");
        List<Double> doubles = new ArrayList<>();
        doubles.add(Double.parseDouble(split[0]));
        doubles.add(Double.parseDouble(split[1]));
        result.add(doubles);
        s = br.readLine();
      }
      return result;
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  public PointSafety getPointSafety(String fileDir, String projectName, String projectTime) {
    PointSafety result = getPointSafetyOutFile(fileDir + File.separator + projectName + "_" + projectTime + ".out");
    if (result == null) {
      return null;
    }
    result.setRollList(getPointSafetyValue(fileDir + File.separator + "value" + File.separator + projectName + "_" + projectTime + ".roll"));
    result.setSurgeList(getPointSafetyValue(fileDir + File.separator + "value" + File.separator + projectName + "_" + projectTime + ".surge"));
    result.setSwayList(getPointSafetyValue(fileDir + File.separator + "value" + File.separator + projectName + "_" + projectTime + ".sway"));
    result.setYawList(getPointSafetyValue(fileDir + File.separator + "value" + File.separator + projectName + "_" + projectTime + ".yaw"));
    return result;
  }

  @Override
  public int creatRoteSafety(RoteSafety roteSafety) {
    StringBuilder sb = new StringBuilder();
    sb
        .append("//                               ProjectName Time                                //").append("\r\n")
        .append(roteSafety.getProjectName()).append(" ").append(roteSafety.getProjectTime()).append("\r\n")
        .append("//                               ship parameters : draft(m) length(m) width(m) displacement(ton) speed(knot/h) direction(deg)  //").append("\r\n")
        .append(roteSafety.getShipDraft() + " " + roteSafety.getShipLength() + " " + roteSafety.getShipWidth() + " " + roteSafety.getShipDisplacement()).append("\r\n");
    creatFile(sb.toString(), roteSafety.getFileDir());
    return 0;
  }

  @Override
  public String runRoteSafety(String roteSafetyDir) {
    String cmdStr = "cmd /c cd /d " + roteSafetyDir + " && rote_safety_analysis.exe";
    return runExe(cmdStr);
  }

  private MainOutFile getRoteSafetyOutFile(String filePath) {
    try {
      MainOutFile result = new MainOutFile();
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      result.setJobName(br.readLine());
      result.setJobTime(br.readLine());
      br.readLine();
      String[] split = br.readLine().split(" ");
      Integer nx = Integer.parseInt(split[0]), ny = Integer.parseInt(split[1]);
      result.setNx(nx);
      result.setNy(ny);
      result.setStartY(Integer.parseInt(split[2]));
      result.setStartX(Integer.parseInt(split[3]));
      result.setEndY(Integer.parseInt(split[4]));
      result.setEndX(Integer.parseInt(split[5]));
      String s1 = br.readLine();
      if (s1.contains(" ")) {
        split = s1.split(" ");
        result.setPointNum(Integer.parseInt(split[0]));
        List<Integer> pointList = new ArrayList<>();
        for (int i = 1; i < split.length; i++) {
          pointList.add(Integer.parseInt(split[i]));
        }
        result.setPointList(pointList);
      } else {
        result.setPointNum(0);
      }
      split = br.readLine().split(" ");
      List<Float> shipVariableList = new ArrayList<>();
      for (String s : split) {
        shipVariableList.add(Float.parseFloat(s));
      }
      result.setShipVariable(shipVariableList);
      result.setModuleType(Integer.parseInt(br.readLine()));

      List<ShipPathAll> shipPathAllList = new ArrayList<>();
      String read = br.readLine();
      while (read != null) {
        String[] splitRead = read.split(" ");
        ShipPathAll shipPathAll = new ShipPathAll();
        shipPathAll.setModuleType(Integer.parseInt(splitRead[0]));
        shipPathAll.setSumDistance(Double.parseDouble(splitRead[1]));
        shipPathAll.setSumTime(Double.parseDouble(splitRead[2]));
        shipPathAll.setSumNumber(Integer.parseInt(splitRead[3]));
        List<ShipPathList> shipPathLists = new ArrayList<>();
        for (int i = 0; i < shipPathAll.getSumNumber(); i++) {
          ShipPathList shipPathList = new ShipPathList();
          splitRead = br.readLine().split(" ");
          shipPathList.setModelType(Integer.parseInt(splitRead[0]));
          shipPathList.setShipPathNumber(Integer.parseInt(splitRead[1]));
          shipPathList.setStartY(Integer.parseInt(splitRead[2]));
          shipPathList.setStartX(Integer.parseInt(splitRead[3]));
          shipPathList.setPointY(Integer.parseInt(splitRead[4]));
          shipPathList.setPointX(Integer.parseInt(splitRead[5]));
          shipPathList.setShipPathDistance(Double.parseDouble(splitRead[6]));
          shipPathList.setShipPathTime(Double.parseDouble(splitRead[7]));
          shipPathList.setShipPathSumNumber(Integer.parseInt(splitRead[8]));
          List<ShipPath> shipPaths = new ArrayList<>();
          for (int j = 0; j < shipPathList.getShipPathSumNumber(); j++) {
            ShipPath shipPath = new ShipPath();
            splitRead = br.readLine().split(" ");
            shipPath.setNum(Integer.parseInt(splitRead[0]));
            shipPath.setStartY(Integer.parseInt(splitRead[1]));
            shipPath.setStartX(Integer.parseInt(splitRead[2]));
            shipPath.setEndY(Integer.parseInt(splitRead[3]));
            shipPath.setEndX(Integer.parseInt(splitRead[4]));
            shipPath.setDistance(Double.parseDouble(splitRead[5]));
            shipPath.setTime(Double.parseDouble(splitRead[6]));
            shipPath.setVelocity(Double.parseDouble(splitRead[7]));
            shipPath.setWindVelocity(Double.parseDouble(splitRead[8]));
            shipPath.setWindDirection(Double.parseDouble(splitRead[9]));
            shipPath.setCurVelocity(Double.parseDouble(splitRead[10]));
            shipPath.setCurDirection(Double.parseDouble(splitRead[11]));
            shipPath.setWaveDirection(Double.parseDouble(splitRead[12]));
            shipPath.setWavePeriod(Double.parseDouble(splitRead[13]));
            shipPath.setWaveHeight(Double.parseDouble(splitRead[14]));
            shipPath.setShipDirection(Double.parseDouble(splitRead[15]));
            shipPath.setSurge(Double.parseDouble(splitRead[16]));
            shipPath.setSway(Double.parseDouble(splitRead[17]));
            shipPath.setYaw(Double.parseDouble(splitRead[18]));
            shipPath.setRoll(Double.parseDouble(splitRead[19]));
            shipPaths.add(shipPath);
          }
          shipPathList.setShipPathList(shipPaths);
          shipPathLists.add(shipPathList);
        }
        shipPathAll.setShipPathLists(shipPathLists);
        shipPathAllList.add(shipPathAll);
        read = br.readLine();
      }
      result.setShipPathAllList(shipPathAllList);
      /*
      List<ShipPathList> shipPathLists = new ArrayList<>();
      ShipPathList shipPathList = new ShipPathList();
      split = br.readLine().split(" ");
//      shipPathList.setModuleType(Integer.parseInt(split[0]));
//      shipPathList.setSumDistance(Double.parseDouble(split[1]));
//      shipPathList.setSumTime(Double.parseDouble(split[2]));

      List<ShipPath> shipPaths = new ArrayList<>();
      String brRead = br.readLine();
      while (brRead != null) {
        String[] split1 = brRead.split(" ");
        if (split1.length == 20) {
          ShipPath shipPath = new ShipPath();
          shipPath.setNum(Integer.parseInt(split1[0]));
          shipPath.setStartX(Integer.parseInt(split1[1]));
          shipPath.setStartY(Integer.parseInt(split1[2]));
          shipPath.setEndX(Integer.parseInt(split1[3]));
          shipPath.setEndY(Integer.parseInt(split1[4]));
          shipPath.setDistance(Double.parseDouble(split1[5]));
          shipPath.setTime(Double.parseDouble(split1[6]));
          shipPath.setVelocity(Double.parseDouble(split1[7]));
          shipPath.setWindVelocity(Double.parseDouble(split1[8]));
          shipPath.setWindDirection(Double.parseDouble(split1[9]));
          shipPath.setCurVelocity(Double.parseDouble(split1[10]));
          shipPath.setCurDirection(Double.parseDouble(split1[11]));
          shipPath.setWaveDirection(Double.parseDouble(split1[12]));
          shipPath.setWavePeriod(Double.parseDouble(split1[13]));
          shipPath.setWaveHeight(Double.parseDouble(split1[14]));
          shipPath.setShipDirection(Double.parseDouble(split1[15]));
          shipPath.setSurge(Double.parseDouble(split1[16]));
          shipPath.setSway(Double.parseDouble(split1[17]));
          shipPath.setYaw(Double.parseDouble(split1[18]));
          shipPath.setRoll(Double.parseDouble(split1[19]));
          shipPaths.add(shipPath);
        } else if (split1.length == 3) {
          shipPathList.setShipPathList(shipPaths);
          shipPaths = new ArrayList<>();
          shipPathLists.add(shipPathList);
          shipPathList = new ShipPathList();
          split = br.readLine().split(" ");
//          shipPathList.setModuleType(Integer.parseInt(split[0]));
//          shipPathList.setSumDistance(Double.parseDouble(split[1]));
//          shipPathList.setSumTime(Double.parseDouble(split[2]));
        }
        brRead = br.readLine();
      }
      shipPathList.setShipPathList(shipPaths);
      shipPathLists.add(shipPathList);
//      result.setShipPathLists(shipPathLists);*/
      return result;
    } catch (Exception e) {
      return null;
    }
  }

  private List<RoteSafetyReport> getRoteSafetyReport(String filePath) {
    try {
      List<RoteSafetyReport> result = new ArrayList<>();
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      RoteSafetyReport report = new RoteSafetyReport();
      String readLine = br.readLine();
      while (readLine != null) {
        if (readLine.contains("safe")) {
          report.setSafe(1);
          result.add(report);
          report = new RoteSafetyReport();
        } else if (readLine.split(" ").length == 3) {
          String[] split = readLine.split(" ");
          report.setModuleType(Integer.parseInt(split[0]));
          report.setSumDistance(Double.parseDouble(split[1]));
          report.setSumTime(Double.parseDouble(split[2]));
        } else if (readLine.split(" ").length == 2) {
          List<Integer> overPointNumber = new ArrayList<>();
          List<Double> overPointRoll = new ArrayList<>();
          while (readLine.split(" ").length == 2) {
            String[] split = readLine.split(" ");
            overPointNumber.add(Integer.parseInt(split[0]));
            overPointRoll.add(Double.parseDouble(split[1]));
            readLine = br.readLine();
          }
          report.setSafe(0);
          report.setOverPointNumber(overPointNumber);
          report.setOverPointRoll(overPointRoll);
          result.add(report);
          report = new RoteSafetyReport();
        }
        readLine = br.readLine();
      }
      return result;
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  public MainOutFile getRoteSafety(String fileDir, String projectName, String projectTime) {
    MainOutFile mainOutFile = getRoteSafetyOutFile(fileDir + File.separator + projectName + ".rot");
//    mainOutFile.setRoteSafetyReports(getRoteSafetyReport(fileDir + File.separator + projectName + "_" + projectTime + ".rot"));
    return mainOutFile;
  }

  @Override
  public int creatShipParameters(RoteSafety roteSafety) {
    StringBuilder sb = new StringBuilder();
    sb
        .append("//                               ProjectName Time                                //").append("\r\n")
        .append(roteSafety.getProjectName()).append(" ").append(roteSafety.getProjectTime()).append("\r\n")
        .append("//                               ship parameters : draft(m) length(m) width(m) displacement(ton) speed(knot/h) direction(deg)  //").append("\r\n")
        .append(roteSafety.getShipDraft() + " " + roteSafety.getShipLength() + " " + roteSafety.getShipWidth() + " " + roteSafety.getShipDisplacement()).append("\r\n");
    creatFile(sb.toString(), roteSafety.getFileDir());
    return 0;
  }

  @Override
  public String runSafetyEnv(String safetyEnvDir) {
    String cmdStr = "cmd /c cd /d " + safetyEnvDir + " && rote_safety_analysis_environment.exe";
    return runExe(cmdStr);
  }

  public PreFile getOutFile(String filePath, Integer variableNum) {
    PreFile preFile = new PreFile();
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(filePath))));
      preFile.setJobName(br.readLine());
      preFile.setJobTime(br.readLine());
      String[] split = br.readLine().split(" ");
      if (split.length >= 4) {
        preFile.setMinLat(Float.parseFloat(split[0]));
        preFile.setMaxLat(Float.parseFloat(split[1]));
        preFile.setMinLon(Float.parseFloat(split[2]));
        preFile.setMaxLon(Float.parseFloat(split[3]));
      }
      split = br.readLine().split(" ");
      if (split.length >= 2) {
        preFile.setNx(Integer.parseInt(split[0]));
        preFile.setNy(Integer.parseInt(split[1]));
      }

      int nx = preFile.getNx();
      int ny = preFile.getNy();

      List<Float[][]> resultList = new ArrayList<>();
      for (int t = 0; t < variableNum; t++) {
        Float[][] result = new Float[ny][nx];
        for (int i = 0; i < ny; i++) {
          split = br.readLine().split(" ");
          for (int j = 0; j < nx; j++) {
            if (split[j].contains("Inf")) {
              result[i][j] = Float.NaN;
//              System.out.println(t + " " + i + " " + j + " " + split[j]);
            } else {
              result[i][j] = Float.parseFloat(split[j]);
            }
          }
        }
        resultList.add(result);
      }
      preFile.setDataArr(resultList);
      return preFile;
    } catch (Exception e) {
      System.out.println("e = " + e);
      return null;
    }
  }

  @Override
  public PreFile getEnvOutFile(String filePath) {
    return getOutFile(filePath, 4);
  }
}
